package com.cf.base.sp;

import com.alibaba.fastjson.JSON;
import com.cf.base.sp.annotation.Delete;
import com.cf.base.sp.annotation.Get;
import com.cf.base.sp.annotation.Level;
import com.cf.base.sp.annotation.Put;
import com.cf.base.sp.engine.impl.MemoryStorageImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class SpCoreP {

    private MemoryStorageImpl storage = new MemoryStorageImpl();

    public <T> T create(Class<T> clsT) {
        return (T) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{clsT}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if (method.getDeclaringClass() == Object.class) {
                    return method.invoke(this, args);
                }
                return parsing(method, args);
            }
        });
    }

    private Object parsing(Method method, Object[] object) {
        Get get = method.getAnnotation(Get.class);
        if (get != null) {
            return parsingGet(method);
        }
        Delete delete = method.getAnnotation(Delete.class);
        if (delete != null) {
            parsingDelete(delete.value());
            return null;
        }
        Put put = method.getAnnotation(Put.class);
        if (put != null) {
            parsingPut(put.value(), object);
        }
        return null;
    }

    private void parsingPut(String value, Object[] object) {
        storage.put(value, JSON.toJSONString(object[0]), Level.Cache);
    }

    private void parsingDelete(String key) {
        storage.delete(key, Level.Cache);
    }

    private Object parsingGet(Method method) {
        Get get = method.getAnnotation(Get.class);
        String key = get.value();
        String content = storage.get(key, Level.Cache);
        return JSON.parseObject(content, method.getGenericReturnType());
    }
}
